/*!
后台服务
- 负责通过UDP接收行情信息
- 并进行加工，压缩数据（时间合并），各种TOP序列的生成。
- 绘制通知 ctx.request_repaint();
- 其他的策略，算法执行。

接收UDP数据依赖foxy,9个字段，顺序定义为：
    1. AveragePrice,
    2. buy,
    3. sell,
    4. InstrumentID,
    5. LastPrice,
    6. OpenPrice,
    7. TradingDay,
    8. UpdateTime,
    9. Volume;
    10. Interest;

修改strategy参数应该是一个日常行为，需要支持自动重载入。为此修改shared config为 RwLock。
但太多的RwLock对象，async原因会导致死锁，所以牺牲空间换逻辑，work内复制一份config，并负责同步shared。

*/

use crate::shared::*;
use crate::*;
//use anyhow::Ok;
use chrono::prelude::*;
use std::collections::HashMap;
use tokio::sync::mpsc;
use tokio::time::Duration;


/**
后台的异步接收行情线程，负责接收UPD发来的行情信息，并进行加工处理和显示通知。
- 借助Arc<Shared>实现与egui线程的数据共享
- 借助egui::Context句柄，实现界面绘制通知。
- 通过broadcast实现优雅关机退出。
*/
pub(crate) struct Worker {
    pub shutdown: shutdown::Shutdown,
    pub _shutdown_complete: mpsc::Sender<()>,
    pub shared: Arc<Shared>,
}

impl Worker {
    /**
    后台的异步执行线程。
    - 可以借助ticker来实现定时策略分析任务。

     */
    pub async fn run(&mut self) -> Result<()> {

        let mut ticker = tokio::time::interval(Duration::from_secs(1));
        ticker.tick().await; // pass 首次

        let mut tasks: HashMap<u32, String> = HashMap::from([
            (905, "third run".to_owned()),
            (1016, "forth".to_owned()),
            (1120, "fifth".to_owned()),
            (1415, "sixth".to_owned()),
            (2105, "first".to_owned()),
            (2220, "second".to_owned()),
        ]);
        let mut counter = 0;    
        let mut rx = self.shared.rx.lock().await;
        // 保存价格突破警戒值的报警，每日清除重置； key = (code, last_price-average/warning)
        // let mut big_vals: HashMap<(String, i32), SimpleTick> = HashMap::new();
        loop {
            tokio::select! {

                     _ = ticker.tick() => {

                         let local:DateTime<Local> = Local::now();
                         let hour = local.hour();
                         let minute = local.minute();
                         let hm = hour*100 + minute;                         
                  
                        if tasks.contains_key(&hm){
                            let msg = format!("{} run task {:?} OK!",hm, tasks.get(&hm));                            
                            tasks.remove(&hm);
                        }else{
                            counter = (counter + 1)%10;
                            if counter == 0 {
                                debug!("{} no task", hm);
                            }
                        }
                     },

                cmd = rx.recv() => {
                    if let Some(cmd) = cmd {
                        debug!("{:?}", cmd);
                    }
                },        
                _ = self.shutdown.recv() => {
                    // If a shutdown signal is received, return from `run`.
                    // This will result in the task terminating.
                    //if let Err(er) = self.global_gen_sync().await {
                    //    error!("{}", er);
                    //}
                    error!("save cache, and close ... OK!");
                    break
                }
            }
        }
        Ok(())
    }
}